 1.Spark GraphX之Spark GraphX基础
   
   GraphX 与 Spark 其他组件相比相对独立，拥有自己的核心数据结构与算子。
   1).GraphX架构
   GraphX的整体架构可以分为三个部分：
      算法层。基于 Pregel 接口实现了常用的图算法。包括 PageRank、SVDPlusPlus、
TriangleCount、 ConnectedComponents、StronglyConnectedConponents 等算法
      接口层。在底层 RDD 的基础之上实现了 Pregel 模型 BSP 模式的计算接口
      底层。图计算的核心类，包含：VertexRDD、EdgeRDD、RDD[EdgeTriplet]
   2).存储模式
   巨型图的存储总体上有边分割和点分割两种存储方式。2013年，GraphLab2.0 将其
存储方式由边分割变为点分割，在性能上取得重大提升，目前基本上被业界广泛接受
并使用。
       边分割（Edge-Cut）：每个顶点都存储一次，但有的边会被打断分到两台机器
上。这样做的好处是节省存储空间；坏处是对图进行基于边的计算时，对于一条两个顶
点被分到不同机器上的边来说，要跨机器通信传输数据，内网通信流量大
       点分割（Vertex-Cut）：每条边只存储一次，都只会出现在一台机器上。邻居
多的点会被复制到多台机器上，增加了存储开销，同时会引发数据同步问题。好处是可
以大幅减少内网通信量
   虽然两种方法互有利弊，但现在是点分割占上风，各种分布式图计算框架都将自己底
层的存储形式变成了点分割。主要原因有以下两个：
       磁盘价格下降，存储空间不再是问题，而内网的通信资源没有突破性进展，集群
计算时内网带宽是宝贵的，时间比磁盘更珍贵。这点就类似于常见的空间换时间的策略；
       在当前的应用场景中，绝大多数网络都是“无尺度网络”，遵循幂律分布,不同点机
的邻居数量相差非常悬殊。而边分割会使那些多邻居的点所相连的边大多数被分到不同的
器上，这样的数据分布会使得内网带宽更加捉襟见肘，于是边分割存储方式被渐渐抛弃了；
   3).核心数据结构
   核心数据结构包括：graph、vertices、edges、triplets
   GraphX API 的开发语言目前仅支持 Scala。GraphX 的核心数据结构 Graph 由 RDD
封装而成。
   (1).Graph
   GraphX 用属性图的方式表示图，顶点有属性，边有属性。存储结构采用边集数组的
形式，即一个顶点表，一个边表，如下图所示：
   顶点 ID 是非常重要的字段，它不光是顶点的唯一标识符，也是描述边的唯一手段。
   顶点表与边表实际上就是 RDD，它们分别为 VertexRDD 与 EdgeRDD。在 Spark 的
源码中，Graph 类如下：
       vertices 为顶点表，VD 为顶点属性类型
       edges 为边表，ED 为边属性类型
       可以通过 Graph 的 vertices 与 edges 成员直接得到顶点 RDD 与边 RDD
       顶点 RDD 类型为 VerticeRDD，继承自 RDD[(VertexId, VD)]
       边 RDD 类型为 EdgeRDD，继承自 RDD[Edge[ED]]
   (2).vertices
   vertices对应着名为 VertexRDD 的RDD。这个RDD由顶点id和顶点属性两个成员变量。
   VertexRDD继承自 RDD[(VertexId, VD)]，这里VertexId表示顶点id，VD表示顶点所
带的属性的类别。
   VertexId 实际上是一个Long类型的数据；
   
   (3).edges
   edges对应着EdgeRDD。这个RDD拥有三个成员变量，分别是源顶点id、目标顶点id
以及边属性。
   Edge代表边，由 源顶点id、目标顶点id、以及边的属性构成。
   (4).triplets
   triplets 表示边点三元组，如下图所示（其中圆柱形分别代表顶点属性与边属性)：
   通过 triplets 成员，用户可以直接获取到起点顶点、起点顶点属性、终点顶点、终点
顶点属性、边与边属性信息。triplets 的生成可以由边表与顶点表通过 ScrId 与DstId 
连接而成。
   triplets对应着EdgeTriplet。它是一个三元组视图，这个视图逻辑上将顶点和边的属
性保存为一个RDD[EdgeTriplet[VD, ED]]。
   
   